import pygame
import random
import sys
import os

# 初始化pygame
pygame.init()

# 游戏常量
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
GROUND_HEIGHT = 500
FPS = 60
GRAVITY = 1
JUMP_FORCE = -20
SPEED = 5

# 颜色
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)
SKIN = (255, 204, 153)  # 皮肤颜色

# 创建游戏窗口
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Parkour Game")
clock = pygame.time.Clock()

# 加载图像（这里用简单图形代替）
def create_surface(width, height, color):
    surface = pygame.Surface((width, height))
    surface.fill(color)
    return surface

# 玩家类 - 使用小人形状
class Player(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        # 创建站立状态的表面
        self.standing_image = pygame.Surface((50, 80), pygame.SRCALPHA)
        self._draw_standing(self.standing_image)
        
        # 创建滑行状态的表面
        self.sliding_image = pygame.Surface((80, 40), pygame.SRCALPHA)
        self._draw_sliding(self.sliding_image)
        
        # 创建跳跃状态的表面
        self.jumping_image = pygame.Surface((50, 80), pygame.SRCALPHA)
        self._draw_jumping(self.jumping_image)
        
        # 设置初始图像
        self.image = self.standing_image
        self.rect = self.image.get_rect()
        self.rect.x = 100
        self.rect.bottom = GROUND_HEIGHT
        self.velocity_y = 0
        self.is_jumping = False
        self.is_sliding = False
        self.slide_time = 0
        
    def _draw_standing(self, surface):
        # 绘制小人站立状态
        pygame.draw.circle(surface, SKIN, (25, 20), 10)  # 头
        pygame.draw.rect(surface, BLUE, (20, 30, 10, 25))  # 身体
        pygame.draw.line(surface, BLUE, (20, 40), (10, 55), 3)  # 左臂
        pygame.draw.line(surface, BLUE, (30, 40), (40, 55), 3)  # 右臂
        pygame.draw.line(surface, BLUE, (20, 55), (15, 75), 3)  # 左腿
        pygame.draw.line(surface, BLUE, (30, 55), (35, 75), 3)  # 右腿
        
    def _draw_sliding(self, surface):
        # 绘制小人滑行状态
        pygame.draw.circle(surface, SKIN, (20, 15), 10)  # 头
        pygame.draw.rect(surface, BLUE, (25, 15, 40, 10))  # 身体
        pygame.draw.line(surface, BLUE, (25, 20), (20, 30), 3)  # 左臂
        pygame.draw.line(surface, BLUE, (65, 20), (70, 30), 3)  # 右臂
        pygame.draw.line(surface, BLUE, (60, 15), (70, 25), 3)  # 右腿
        pygame.draw.line(surface, BLUE, (45, 15), (35, 25), 3)  # 左腿
        
    def _draw_jumping(self, surface):
        # 绘制小人跳跃状态
        pygame.draw.circle(surface, SKIN, (25, 20), 10)  # 头
        pygame.draw.rect(surface, BLUE, (20, 30, 10, 25))  # 身体
        pygame.draw.line(surface, BLUE, (20, 40), (10, 30), 3)  # 左臂向上
        pygame.draw.line(surface, BLUE, (30, 40), (40, 30), 3)  # 右臂向上
        pygame.draw.line(surface, BLUE, (20, 55), (10, 65), 3)  # 左腿弯曲
        pygame.draw.line(surface, BLUE, (30, 55), (40, 65), 3)  # 右腿弯曲
        
    def update(self):
        # 重力效果
        self.velocity_y += GRAVITY
        self.rect.y += self.velocity_y
        
        # 确保角色不会掉出地面
        if self.rect.bottom > GROUND_HEIGHT:
            self.rect.bottom = GROUND_HEIGHT
            self.velocity_y = 0
            self.is_jumping = False
            self.is_sliding = False
            self.image = self.standing_image  # 回到站立状态
            
        # 滑行动画计时
        if self.is_sliding:
            self.slide_time += 1
            if self.slide_time > 30:  # 滑行持续时间
                self.is_sliding = False
                self.image = self.standing_image
                self.rect.height = 80
                self.rect.y = GROUND_HEIGHT - 80
                
    def jump(self):
        if not self.is_jumping and not self.is_sliding:
            self.velocity_y = JUMP_FORCE
            self.is_jumping = True
            self.is_sliding = False
            self.image = self.jumping_image
            # 不需要改变矩形位置，重力会处理
            
    def slide(self):
        if not self.is_jumping and not self.is_sliding:
            self.is_sliding = True
            self.slide_time = 0
            self.image = self.sliding_image
            self.rect.height = 40
            self.rect.y = GROUND_HEIGHT - 40

# 障碍物类
class Obstacle(pygame.sprite.Sprite):
    def __init__(self, x, y, width, height, obstacle_type):
        super().__init__()
        self.obstacle_type = obstacle_type  # 1: low obstacle 2: high obstacle 3: continuous obstacle
        
        if obstacle_type == 1:  # low obstacle (need to jump)
            self.image = create_surface(width, height, GREEN)
        elif obstacle_type == 2:  # high obstacle (need to slide)
            self.image = create_surface(width, height, RED)
        else:  # continuous obstacle
            self.image = create_surface(width, height, YELLOW)
            
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.bottom = y
        
    def update(self):
        self.rect.x -= SPEED
        if self.rect.right < 0:
            self.kill()

# 金币类
class Coin(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.Surface((30, 30), pygame.SRCALPHA)
        pygame.draw.circle(self.image, YELLOW, (15, 15), 15)
        pygame.draw.circle(self.image, (200, 170, 0), (15, 15), 12)
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        
    def update(self):
        self.rect.x -= SPEED
        if self.rect.right < 0:
            self.kill()

# 游戏类
class Game:
    def __init__(self):
        self.player = Player()
        self.all_sprites = pygame.sprite.Group(self.player)
        self.obstacles = pygame.sprite.Group()
        self.coins = pygame.sprite.Group()
        self.score = 0
        self.coin_count = 0
        self.distance = 0
        self.obstacle_timer = 0
        self.coin_timer = 0
        self.game_over = False
        self.font = pygame.font.SysFont(None, 36)
        
    def spawn_obstacle(self):
        obstacle_type = random.randint(1, 3)
        height = 0
        
        if obstacle_type == 1:  # low obstacle
            height = random.randint(30, 60)
        elif obstacle_type == 2:  # high obstacle
            height = random.randint(100, 150)
        else:  # continuous obstacle
            height = random.randint(50, 80)
            
        obstacle = Obstacle(SCREEN_WIDTH, GROUND_HEIGHT, 30, height, obstacle_type)
        self.obstacles.add(obstacle)
        self.all_sprites.add(obstacle)
        
    def spawn_coin(self):
        y = random.randint(GROUND_HEIGHT - 200, GROUND_HEIGHT - 50)
        coin = Coin(SCREEN_WIDTH, y)
        self.coins.add(coin)
        self.all_sprites.add(coin)
        
    def check_collisions(self):
        # 检查与障碍物的碰撞
        hits = pygame.sprite.spritecollide(self.player, self.obstacles, False)
        if hits:
            for obstacle in hits:
                # 根据障碍物类型和玩家状态判断是否碰撞
                if obstacle.obstacle_type == 1:  # 矮障碍物需要跳跃
                    if not self.player.is_jumping:
                        self.game_over = True
                elif obstacle.obstacle_type == 2:  # 高障碍物需要滑行
                    if not self.player.is_sliding:
                        self.game_over = True
                else:  # 连续障碍物需要跳跃或滑行
                    if not (self.player.is_jumping or self.player.is_sliding):
                        self.game_over = True
                    
        # 检查与金币的碰撞
        coin_hits = pygame.sprite.spritecollide(self.player, self.coins, True)
        for coin in coin_hits:
            self.coin_count += 1
            self.score += 10
            
    def update(self):
        if not self.game_over:
            self.all_sprites.update()
            self.distance += 1
            self.score = self.distance // 10 + self.coin_count * 10
            
            # 生成障碍物
            self.obstacle_timer += 1
            if self.obstacle_timer > random.randint(60, 120):
                self.spawn_obstacle()
                self.obstacle_timer = 0
                
            # 生成金币
            self.coin_timer += 1
            if self.coin_timer > random.randint(30, 90):
                self.spawn_coin()
                self.coin_timer = 0
                
            self.check_collisions()
            
    def draw(self):
        # 添加渐变背景
        for y in range(SCREEN_HEIGHT):
            # 从顶部的浅蓝色到底部的深蓝色渐变
            color = (50, 150 - y//4, 200 - y//3)
            pygame.draw.line(screen, color, (0, y), (SCREEN_WIDTH, y))
        
        # 绘制地面
        pygame.draw.rect(screen, (100, 70, 30), (0, GROUND_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT - GROUND_HEIGHT))
        # 绘制草地
        pygame.draw.rect(screen, (34, 139, 34), (0, GROUND_HEIGHT - 10, SCREEN_WIDTH, 10))
        
        # 绘制所有精灵
        self.all_sprites.draw(screen)
        
        # 绘制分数
        score_text = self.font.render(f"Score: {self.score}", True, WHITE)
        distance_text = self.font.render(f"Distance: {self.distance}", True, WHITE)
        coin_text = self.font.render(f"Coins: {self.coin_count}", True, WHITE)
        
        screen.blit(score_text, (10, 10))
        screen.blit(distance_text, (10, 50))
        screen.blit(coin_text, (10, 90))
        
        # 绘制控制说明
        controls_text = self.font.render("Space/Up: Jump | Down: Slide | Left-click: Jump | Right-click: Slide", True, WHITE)
        screen.blit(controls_text, (SCREEN_WIDTH//2 - controls_text.get_width()//2, SCREEN_HEIGHT - 30))
        
        # 游戏结束显示
        if self.game_over:
            game_over_surface = pygame.Surface((400, 200), pygame.SRCALPHA)
            game_over_surface.fill((0, 0, 0, 180))
            screen.blit(game_over_surface, (SCREEN_WIDTH//2 - 200, SCREEN_HEIGHT//2 - 100))
            
            game_over_text = self.font.render("Game Over!", True, RED)
            restart_text = self.font.render("Press R to restart", True, WHITE)
            final_score = self.font.render(f"Final Score: {self.score}", True, YELLOW)
            
            screen.blit(game_over_text, (SCREEN_WIDTH//2 - game_over_text.get_width()//2, SCREEN_HEIGHT//2 - 50))
            screen.blit(final_score, (SCREEN_WIDTH//2 - final_score.get_width()//2, SCREEN_HEIGHT//2 - 10))
            screen.blit(restart_text, (SCREEN_WIDTH//2 - restart_text.get_width()//2, SCREEN_HEIGHT//2 + 30))
            
    def handle_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return False
                
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE or event.key == pygame.K_UP:
                    self.player.jump()
                elif event.key == pygame.K_DOWN:
                    self.player.slide()
                elif event.key == pygame.K_r and self.game_over:
                    self.__init__()  # 重置游戏
                    
        # 鼠标控制
        mouse_pos = pygame.mouse.get_pos()
        mouse_click = pygame.mouse.get_pressed()
        
        if mouse_click[0]:  # 左键点击 - 跳跃
            if not self.player.is_jumping and not self.player.is_sliding:
                self.player.jump()
                
        if mouse_click[2]:  # 右键点击 - 滑行
            if not self.player.is_jumping and not self.player.is_sliding:
                self.player.slide()
                
        return True

# 主游戏循环
def main():
    game = Game()
    running = True
    
    while running:
        running = game.handle_events()
        game.update()
        game.draw()
        
        pygame.display.flip()
        clock.tick(FPS)
        
    pygame.quit()
    sys.exit()

if __name__ == "__main__":
    main()